﻿#include "jsimdvector.h"
#include "simd_cph/include/simd_cp.h"

// - class JSimdVector -

JSimdVector::JSimdVector()
{

}

JSimdVector::~JSimdVector()
{

}

void JSimdVector::plus(const char a[], const char b[], char c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 16;
    while (--index >= 0) {
        simd_16c_add(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 16);
    while (index < length) {
        c[index] = a[index] + b[index];
        ++index;
    }
}

void JSimdVector::plus(const short a[], const short b[], short c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 8;
    while (--index >= 0) {
        simd_8s_add(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 8);
    while (index < length) {
        c[index] = a[index] + b[index];
        ++index;
    }
}

void JSimdVector::plus(const int a[], const int b[], int c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4i_add(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] + b[index];
        ++index;
    }
}

void JSimdVector::plus(const float a[], const float b[], float c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4f_add(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] + b[index];
        ++index;
    }
}

void JSimdVector::minus(const char a[], const char b[], char c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 16;
    while (--index >= 0) {
        simd_16c_sub(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 16);
    while (index < length) {
        c[index] = a[index] - b[index];
        ++index;
    }
}

void JSimdVector::minus(const short a[], const short b[], short c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 8;
    while (--index >= 0) {
        simd_8s_sub(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 8);
    while (index < length) {
        c[index] = a[index] - b[index];
        ++index;
    }
}

void JSimdVector::minus(const int a[], const int b[], int c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4i_sub(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] - b[index];
        ++index;
    }
}

void JSimdVector::minus(const float a[], const float b[], float c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4f_sub(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] - b[index];
        ++index;
    }
}

void JSimdVector::mult(const float a[], const float b[], float c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4f_mlt(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] * b[index];
        ++index;
    }
}

/**
 * @brief JSimdVector::div
 * @param a
 * @param b
 * @param c
 * @param length
 */
void JSimdVector::div(const float a[], const float b[], float c[], int length)
{
    simd_m128 *pa = (simd_m128 *)a;
    simd_m128 *pb = (simd_m128 *)b;
    simd_m128 *pc = (simd_m128 *)c;

    int index = length / 4;
    while (--index >= 0) {
        simd_4f_div(pa[index], pb[index], pc[index]);
    }

    simd_empty();

    // left
    index = length - (length % 4);
    while (index < length) {
        c[index] = a[index] / b[index];
        ++index;
    }
}
